package hyl.base.ntty.utils;

import static io.netty.buffer.Unpooled.copiedBuffer;
import static io.netty.handler.codec.http.HttpHeaderNames.*;
import static io.netty.handler.codec.http.HttpResponseStatus.*;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.activation.MimetypesFileTypeMap;

import com.alibaba.fastjson.JSONObject;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpResponse;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpUtil;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.handler.codec.http.multipart.InterfaceHttpData;
import io.netty.handler.codec.http.multipart.MemoryAttribute;
import io.netty.util.CharsetUtil;

public class HttpTools {

	// 重定向操作
	public static void sendRedirect(ChannelHandlerContext ctx, String newUri) {
		// 建立响应对象
		FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, FOUND);
		// 设置新的请求地址放入响应对象中去
		response.headers().set(HttpHeaderNames.LOCATION, newUri);
		/*
		 * 使用ctx对象写出并且刷新到SocketChannel中去 并主动关闭连接(这里是指关闭处理发送数据的线程连接)
		 */
		ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
	}

	// 错误信息
	public static void sendErrorPage(ChannelHandlerContext ctx) {
		// 建立响应对象
		sendRedirect(ctx, "/404.jsp");
		/*
		 * 使用ctx对象写出并且刷新到SocketChannel中去 并主动关闭连接(这里是指关闭处理发送数据的线程连接)
		 */

	}

	public static String setURL去参数(String url) {	
		return url.substring(0,url.indexOf("?"));
	}
	public static void setContentTypeHeader(HttpResponse response, File file) {
		MimetypesFileTypeMap mimetypesFileTypeMap = new MimetypesFileTypeMap();
		response.headers().set(HttpHeaderNames.CONTENT_TYPE, mimetypesFileTypeMap.getContentType(file.getPath()));
	}

	public static Map<String, Object> getFormParams(FullHttpRequest fullHttpRequest) {
		Map<String, Object> params = new HashMap<String, Object>();
		// HttpPostMultipartRequestDecoder
		HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(false), fullHttpRequest);
		List<InterfaceHttpData> postData = decoder.getBodyHttpDatas();
		for (InterfaceHttpData data : postData) {
			if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute) {
				MemoryAttribute attribute = (MemoryAttribute) data;
				params.put(attribute.getName(), attribute.getValue());
			}
		}
		return params;
	}

	public static Map<String, Object> getJSONParams(FullHttpRequest fullHttpRequest)
			throws UnsupportedEncodingException {
		Map<String, Object> params = new HashMap<String, Object>();
		ByteBuf content = fullHttpRequest.content();
		byte[] reqContent = new byte[content.readableBytes()];
		content.readBytes(reqContent);
		String strContent = new String(reqContent, "UTF-8");
		JSONObject jsonObject = JSONObject.parseObject(strContent);
		for (String key : jsonObject.keySet()) {
			params.put(key, jsonObject.get(key));
		}
		return params;
	}

	public static void set跨域访问(FullHttpResponse response) {
		response.headers().set(ACCESS_CONTROL_ALLOW_ORIGIN, "*");
		response.headers().set(ACCESS_CONTROL_ALLOW_HEADERS, "Origin, X-Requested-With, Content-Type, Accept");
		response.headers().set(ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, PUT,DELETE");
	}


	// 返回text
	public static FullHttpResponse getTextResponse(HttpResponseStatus status, String responseContent) {
		ByteBuf content = copiedBuffer(responseContent, CharsetUtil.UTF_8);
		FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, content);
		response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain;charset=UTF-8;");
		response.headers().set("Content-Length", response.content().readableBytes());
		return response;
	}

	// 返回json
	public static FullHttpResponse getJsonResponse(HttpResponseStatus status, String jsonResult) {
		// 建立响应对象
		FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status,
				Unpooled.copiedBuffer(jsonResult, CharsetUtil.UTF_8));
		// 设置响应头信息
		response.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json; charset=UTF-8");
		return response;
		/*
		 * 使用ctx对象写出并且刷新到SocketChannel中去 并主动关闭连接(这里是指关闭处理发送数据的线程连接)
		 */
		// ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
	}

	public static Map<String, Object> getGET参数(FullHttpRequest fullHttpRequest) {

		
			Map<String, Object> params = new HashMap<String, Object>();
			QueryStringDecoder decoder = new QueryStringDecoder(fullHttpRequest.uri());

			Map<String, List<String>> paramList = decoder.parameters();
			if (paramList.isEmpty())
				return null;
			for (Map.Entry<String, List<String>> entry : paramList.entrySet()) {
				params.put(entry.getKey(), entry.getValue().get(0));
			}
			return params;
	
	}

	public static Map<String, Object> getPost参数(FullHttpRequest fullHttpRequest) {

		
			Map<String, Object> params = new HashMap<String, Object>();
			String strContentType = fullHttpRequest.headers().get("Content-type").trim();
//	            if (strContentType.contains("x-www-form-urlencoded")) {
			if (strContentType.contains("form")) {
				params = getFormParams(fullHttpRequest);
				if (params.isEmpty())
					return null;
			} else if (strContentType.contains("application/json")) {
				try {
					params = getJSONParams(fullHttpRequest);
					if (params.isEmpty())
						return null;
				} catch (UnsupportedEncodingException e) {
					return null;
				}
			} else {
				return null;
			}
			return params;

	}

	/**
	 * 
	 *
	 * 
	 * @param ctx
	 * @param response
	 */
	public static void writeAndClose(ChannelHandlerContext ctx, FullHttpResponse response) {
		// 写入完成时立即通知监听器
		ctx.write(response).addListener(ChannelFutureListener.CLOSE);
		// 坑 在Netty内部所有的操作都是异步的, 那么如果用 ctx.close()会在写入完成前提前执行
		// 所以只能用.addListener(ChannelFutureListener.CLOSE); 在写入完成后关闭
	}

	public static boolean isKeepAlive(FullHttpRequest request) {
		return HttpUtil.isKeepAlive(request);
	}

	/**
	 * 在HTTP/1.0里，默认关闭 keep-aliv
	 * 在HTTP/1.1里，默认是开启了keep-alive，要关闭keep-alive需要在HTTP请求头里显示指定
	 * 
	 * @param response
	 */
	public static void setKeepAlive(FullHttpResponse response, boolean 开启) {
		if (开启)
			response.headers().set(CONNECTION, "keep-alive");
		else
			response.headers().set(CONNECTION, "close");
	}
	public static void set发送缓存(FullHttpResponse response ,String size) {
		response.headers().set("SO_SNDBUF", size);
	}
	/**
	 * 
	 * @param ctx
	 * @param response
	 * @param request
	 */
	public static void write(ChannelHandlerContext ctx, FullHttpResponse response) {
		ctx.write(response);
		ctx.flush();

	}
}
